home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_asm / 68kdis / iset.c < prev    next >
C/C++ Source or Header  |  1988-12-02  |  25KB  |  1,223 lines

  1. /*
  2.  *    SCCS:    @(#)iset.c    1.2    11/2/84    14:18:23
  3.  *    Decode instructions.
  4.  *
  5.  ***********************************************************************
  6.  *    This software is copyright of
  7.  *
  8.  *        John M Collins
  9.  *        47 Cedarwood Drive
  10.  *        St Albans
  11.  *        Herts, AL4 0DN
  12.  *        England            +44 727 57267
  13.  *
  14.  *    and is released into the public domain on the following conditions:
  15.  *
  16.  *        1.  No free maintenance will be guaranteed.
  17.  *        2.  Nothing may be based on this software without
  18.  *            acknowledgement, including incorporation of this
  19.  *            notice.
  20.  *
  21.  *    Notwithstanding the above, the author welcomes correspondence and bug
  22.  *    fixes.
  23.  ***********************************************************************
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <a.out.h>
  28. #include <ldfcn.h>
  29. #include "unc.h"
  30.  
  31. ef_fids    mainfile;
  32. long    endt;
  33.  
  34. void    gette(), putte();
  35. void    mkdref();
  36. long    gettw();
  37. symbol    textlab();
  38.  
  39. int    l1(), l2(), el1(), lea(), lmove(), lcbch(), jj();
  40. int    limed(), lsbit(), lmvml(), lone(), loone(), lonew(), lonel();
  41.  
  42. int    pmove(), pcbch(), pdbcc(), pscc(), pcs(), pmovc(), pstop(), pexg();
  43. int    pimed(), pmovp(), psbit(), pdbit(), pcs2(), pone(), ppea();
  44. int    plea(), pdreg(), pmvml(), ptrap(), plink(), pareg(), podreg();
  45. int    pqu(), pmqu(), ptreg(), pcmpm(), pomode(), pmshf(), pshf();
  46.  
  47. struct    opstr    {
  48.     unsigned  short     mask;
  49.     unsigned  short  match;
  50.     int    (*opsize)();
  51.     int    (*opprin)();
  52.     char    *prarg;
  53. } optab[] = {
  54.     0xf000, 0x2000, lmove, pmove, ".l",
  55.     0xf000, 0x3000, lmove, pmove, ".w",
  56.     0xf000, 0x1000, lmove, pmove, ".b",
  57.     0xf000, 0x6000, lcbch, pcbch, 0,
  58.     0xffbf, 0x003c, l2,    pcs,   "or",
  59.     0xff00, 0x0000, limed, pimed, "or",
  60.     0xffbf, 0x023c, l2,    pcs,   "and",
  61.     0xff00, 0x0200, limed, pimed, "and",
  62.     0xff00, 0x0400, limed, pimed, "sub",
  63.     0xff00, 0x0600, limed, pimed, "add",
  64.     0xffbf, 0x0a3c, l2,    pcs,   "eor",
  65.     0xff00, 0x0a00, limed, pimed, "eor",
  66.     0xff00, 0x0c00, limed, pimed, "cmp",
  67.     0xf138, 0x0108, l2,    pmovp, 0,
  68.     0xff00, 0x0800, lsbit, psbit, 0,
  69.     0xf100, 0x0100, lonew, pdbit, 0,
  70.     0xffc0, 0x40c0, lonew, pcs2,  "sr",
  71.     0xff00, 0x4000, lone,  pone,  "negx",
  72.     0xff00, 0x4200, lone,  pone,  "clr",
  73.     0xffc0, 0x44c0, lonew, pcs2,  "cc",
  74.     0xff00, 0x4400, lone,  pone,  "neg",
  75.     0xffc0, 0x46c0, lonew, pcs2,  "sr",
  76.     0xff00, 0x4600, lone,  pone,  "not",
  77.     0xffc0, 0x4800, lonew, ppea,  "nbcd",
  78.     0xfff8, 0x4840, l1,    pdreg, "swap.w",
  79.     0xffc0, 0x4840, lonel, ppea,  "pea",
  80.     0xfff8, 0x4880, l1,    pdreg, "ext.w",
  81.     0xfff8, 0x48c0, l1,    pdreg, "ext.l",
  82.     0xfb80, 0x4880, lmvml, pmvml, 0,
  83.     0xffc0, 0x4ac0, lonew, ppea,  "tas",
  84.     0xff00, 0x4a00, lone,  pone,  "tst",
  85.     0xfff0, 0x4e40, l1,    ptrap, 0,
  86.     0xfff8, 0x4e50, l2,    plink, 0,
  87.     0xfff8, 0x4e58, l1,    pareg, "unlk\t%s",
  88.     0xfff8, 0x4e60, l1,    pareg, "mov.l\t%s,%%usp",
  89.     0xfff8, 0x4e68, l1,    pareg, "mov.l\t%%usp,%s",
  90.     0xffff, 0x4e70, l1,    pareg, "reset",
  91.     0xffff, 0x4e71, l1,    pareg, "nop",
  92.     0xffff, 0x4e72, l2,    pstop, 0,
  93.     0xffff, 0x4e73, el1,   pareg, "rte",
  94.     0xffff, 0x4e75, el1,   pareg, "rts",
  95.     0xffff, 0x4e76, l1,    pareg, "trapv",
  96.     0xffff, 0x4e77, el1,   pareg, "rtr",
  97.     0xfffe, 0x4e7a, l2,    pmovc, 0,
  98.     0xffc0, 0x4e80, jj,    ppea,  "jsr",
  99.     0xffc0, 0x4ec0, jj,    ppea,  "jmp",
  100.     0xf1c0, 0x4180, lonew, podreg,"chk",
  101.     0xf1c0, 0x41c0, lonel, plea,  0,
  102.     0xf0f8, 0x50c8, lcbch, pdbcc, 0,
  103.     0xf0c0, 0x50c0, lonew, pscc,  0,
  104.     0xf100, 0x5000, lone,  pqu,   "add",
  105.     0xf100, 0x5100, lone,  pqu,   "sub",
  106.     0xf100, 0x7000, l1,    pmqu,  0,
  107.     0xf1c0, 0x80c0, lonew, podreg,"divu",
  108.     0xf1c0, 0x81c0, lonew, podreg,"divs",
  109.     0xf1f0, 0x8100, l1,    ptreg, "sbcd",
  110.     0xf000, 0x8000, loone, pomode,"or",
  111.     0xf1f0, 0x9100, l1,    ptreg, "subx.b",
  112.     0xf1f0, 0x9140, l1,    ptreg, "subx.w",
  113.     0xf1f0, 0x9180, l1,    ptreg, "subx.l",
  114.     0xf000, 0x9000, loone, pomode,"sub",
  115.     0xf1f8, 0xb108, l1,    pcmpm, "cmp.b",        /* CMPM    */
  116.     0xf1f8, 0xb148, l1,    pcmpm, "cmp.w",        /* CMPM    */
  117.     0xf1f8, 0xb188, l1,    pcmpm, "cmp.l",        /* CMPM    */
  118.     0xf100, 0xb000, loone, pomode,"cmp",
  119.     0xf1c0, 0xb1c0, loone, pomode,"cmp",
  120.     0xf100, 0xb100, loone, pomode,"eor",
  121.     0xf1c0, 0xc0c0, lonew, podreg,"mulu",
  122.     0xf1c0, 0xc1c0, lonew, podreg,"muls",
  123.     0xf1f0, 0xc100, l1,    ptreg, "abcd",
  124.     0xf130, 0xc100, l1,    pexg,  0,
  125.     0xf000, 0xc000, loone, pomode,"and",
  126.     0xf1f0, 0xd100, l1,    ptreg, "addx.b",
  127.     0xf1f0, 0xd140, l1,    ptreg, "addx.w",
  128.     0xf1f0, 0xd180, l1,    ptreg, "addx.l",
  129.     0xf000, 0xd000, loone, pomode,"add",
  130.     0xf8c0, 0xe0c0, lonew, pmshf,  0,
  131.     0xf000, 0xe000, l1,    pshf,   0,
  132.     0
  133. };
  134.  
  135. char    *areg[] = { "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp"};
  136. char    *cclist[] = { "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs",
  137.             "pl", "mi", "ge", "lt", "gt", "le"};
  138.     
  139. char    *shtype[] = { "as", "ls", "rox", "ro" };
  140. char    *bittyp[] = { "tst", "chg", "clr", "set" };
  141.  
  142. char    *creg[] = { "%sfc", "%dfc", "%usp", "%vbr" };
  143.  
  144. int swbegflg = 0;
  145.  
  146. /*
  147.  *    Length functions.
  148.  */
  149.  
  150. int    l1()
  151. {
  152.     return    1;
  153. }
  154.  
  155. int    l2()
  156. {
  157.     return    2;
  158. }
  159.  
  160. int    el1(te)
  161. t_entry    *te;
  162. {
  163.     te->t_bchtyp = T_UNBR;
  164.     return    1;
  165. }
  166.  
  167. int    lea(instr, size, pos)
  168. unsigned  instr, size;
  169. long    pos;
  170. {
  171.     switch  ((instr >> 3) & 0x7)  {
  172.     case  0:
  173.     case  1:
  174.     case  2:
  175.     case  3:
  176.     case  4:
  177.         return    1;
  178.     case  5:
  179.     case  6:
  180.         return    2;
  181.     default:
  182.         switch  (instr & 0x7)  {
  183.         case  0:
  184.         case  2:
  185.         case  3:
  186.             return    2;
  187.         case  1:
  188.             mkdref(pos, size);
  189.             return    3;
  190.         case  4:
  191.             if  (size > 2)
  192.                 return    3;
  193.             return    2;
  194.         default:
  195.             return    0;
  196.         }
  197.     }
  198. }
  199.  
  200. /*
  201.  *    Lengths of move instructions.
  202.  */
  203.  
  204. int    lmove(te, pos)
  205. t_entry    *te;
  206. long    pos;
  207. {
  208.     register  unsigned  tc  =  te->t_contents;
  209.     unsigned  sz  =  1;
  210.     int    lng, lng2;
  211.     
  212.     lng  = tc & 0xf000;
  213.     if  (lng == 0x3000)
  214.         sz = 2;
  215.     else  if  (lng == 0x2000)
  216.         sz = 4;
  217.     
  218.     if  ((lng = lea(tc, sz, pos+2)) <= 0)
  219.         return    0;
  220.     lng2 = lea(((tc>>3) & 0x38) | ((tc>>9) & 0x7), sz, pos+lng+lng);
  221.     if  (lng2 <= 0)
  222.         return    0;
  223.     return    lng + lng2 - 1;
  224. }
  225.  
  226. /*
  227.  *    Lengths for conditional branches and dbcc instructions.
  228.  */
  229.  
  230. int    lcbch(te, pos)
  231. t_entry    *te;
  232. long    pos;
  233. {
  234.     unsigned  tc  =  te->t_contents;
  235.     long    dest  =  pos + 2;
  236.     int    res   =  2;
  237.     
  238.     if  ((tc & 0xf000) == 0x5000  ||  (tc & 0xff) == 0)
  239.         dest += (short)gettw(&mainfile, pos+2, R_WORD);
  240.     else  {
  241.         dest += (char) tc;
  242.         res = 1;
  243.     }
  244.      if ( dest < 0x290000 && (dest < mainfile.ef_tbase 
  245.          || dest >= mainfile.ef_tbase+mainfile.ef_tsize 
  246.          || (dest & 1) != 0 ))
  247.          return 0;        /* Illegal branch destination */
  248.     if  ((tc & 0xff00) == 0x6000)
  249.         te->t_bchtyp = T_UNBR;
  250.     else  if  ((tc & 0xff00) == 0x6100)
  251.         te->t_bchtyp = T_JSR;
  252.     else
  253.         te->t_bchtyp = T_CONDBR;
  254.  
  255.      if ( dest < 0x290000 && ((te->t_relsymb = textlab(dest, pos)) == NULL )) {
  256.          te->t_bchtyp = T_NOBR;/* Branch to a continuation */
  257.          return 0;
  258.      }
  259.     return    res;
  260. }
  261.  
  262. int    jj(te, pos)
  263. t_entry    *te;
  264. long    pos;
  265. {
  266.     unsigned  tc  =  te->t_contents;
  267.     t_entry    nextl;
  268.      long dest;
  269.     
  270.     te->t_bchtyp = (tc & 0x40)? T_UNBR: T_JSR;
  271.     if ((tc & 0x3f) == 0x39) {
  272.         gette(&mainfile, pos+2, &nextl);
  273.         if  (nextl.t_relsymb == NULL)  {
  274.              dest = gettw(&mainfile, pos + 2, R_LONG );
  275.              if ( dest < 0x290000 && (dest < mainfile.ef_tbase
  276.                  || dest >= mainfile.ef_tbase+mainfile.ef_tsize
  277.                  || (dest & 1) != 0 ))
  278.                  return 0;    /* Illegal branch destination */
  279.              if ( dest < 0x290000 && ( nextl.t_relsymb = textlab(dest, pos) ) == NULL )
  280.              return 0;    /* Branch to a continuation */
  281.             putte(&mainfile, pos+2, &nextl);
  282.         }
  283.         te->t_relsymb = nextl.t_relsymb;    /*  Easy ref  */
  284.     }
  285.     else if ((tc & 0x3f) == 0x3a) {
  286.         gette(&mainfile, pos+2, &nextl);
  287.         if  (nextl.t_relsymb == NULL)  {
  288.             dest = pos+2+ (int)((short) 
  289.                 gettw(&mainfile, pos + 2, R_WORD ));
  290.              if ( dest < 0x290000 && (dest < mainfile.ef_tbase
  291.                  || dest >= mainfile.ef_tbase+mainfile.ef_tsize
  292.                  || (dest & 1) != 0 ))
  293.             return    lea(tc, 4, pos+2);
  294.              if (dest < 0x290000 && 
  295.                 (nextl.t_relsymb = textlab(dest, pos)) == NULL)
  296.                  return 0;    /* Branch to a continuation */
  297.             putte(&mainfile, pos+2, &nextl);
  298.         }
  299.         te->t_relsymb = nextl.t_relsymb;    /*  Easy ref  */
  300.     }
  301.     return    lea(tc, 4, pos+2);
  302. }
  303.  
  304. int    limed(te, pos)
  305. t_entry    *te;
  306. long    pos;
  307. {
  308.     unsigned  tc  =  te->t_contents;
  309.     int    lng;
  310.     
  311.     /*
  312.      *    Specifically exclude byte address register operands,
  313.      *    and ones which have lengths of 3.
  314.      */
  315.  
  316.     if  ((tc & 0xf8) == 0x08)
  317.         return  0;
  318.     
  319.     if  ((tc & 0xc0) >= 0x80)  {
  320.         if  (tc & 0x40)
  321.             return  0;
  322.         lng = lea(tc, 4, pos+6);
  323.         if  (lng > 0)
  324.             lng += 2;
  325.     }
  326.     else  {
  327.         lng = lea(tc, (unsigned)((tc & 0xc0)?2:1), pos+4);
  328.         if  (lng > 0)
  329.             lng++;
  330.     }
  331.     return    lng;
  332. }
  333.  
  334. int    lsbit(te, pos)
  335. t_entry    *te;
  336. long    pos;
  337. {
  338.     int    lng = lea(te->t_contents, 1, pos+4);
  339.     
  340.     if  (lng > 0)
  341.         lng++;
  342.     return    lng;
  343. }
  344.  
  345. int    lmvml(te, pos)
  346. t_entry    *te;
  347. long    pos;
  348. {
  349.     int    lng = lea(te->t_contents,
  350.             (unsigned)(te->t_contents&0x40? 4:2), pos+4);
  351.     
  352.     if  (lng > 0)
  353.         lng++;
  354.     return    lng;
  355. }
  356.  
  357. /*
  358.  *    Length depends on bits 6 and 7 of instruction.
  359.  */
  360.  
  361. int    lone(te, pos)
  362. t_entry    *te;
  363. long    pos;
  364. {
  365.     unsigned  tc  =  te->t_contents;
  366.     
  367.     return    lea(tc, 1 << ((tc >> 6) & 3), pos+2);
  368. }
  369.  
  370. /*
  371.  *    Length depends on bits 6-8 of instruction.
  372.  */
  373.  
  374. int    loone(te, pos)
  375. t_entry    *te;
  376. long    pos;
  377. {
  378.     unsigned  tc  =  te->t_contents;
  379.     
  380.     switch  ((tc >> 6) & 7)  {
  381.     case  0:
  382.     case  4:
  383.         return    lea(tc, 1, pos+2);
  384.     case  1:
  385.     case  3:
  386.     case  5:
  387.         return  lea(tc, 2, pos+2);
  388.     case  2:
  389.     case  6:
  390.     case  7:
  391.         return    lea(tc, 4, pos+2);
  392.     }
  393.     /*NOTREACHED*/
  394. }
  395.  
  396. int    lonew(te, pos)
  397. t_entry    *te;
  398. long    pos;
  399. {
  400.     if (te->t_contents == 0x4afc) { /* swbeg ... */
  401.         swbegflg++;
  402.         return (2 + gettw(&mainfile,pos+2,2));
  403.     }
  404.     return    lea(te->t_contents, 2, pos+2);
  405. }
  406.  
  407. int    lonel(te, pos)
  408. t_entry    *te;
  409. long    pos;
  410. {
  411.     return    lea(te->t_contents, 4, pos+2);
  412. }
  413.  
  414. /*
  415.  *    Print routines.
  416.  */
  417.  
  418. /*
  419.  * print out small integers in decamil notation, all others in hex.
  420.  */
  421.  
  422. void prind(n)
  423. unsigned short n;
  424. {
  425.     if ((short) n > -128 && (short) n < 128)
  426.         (void) printf("%d", (long) ((short) n));
  427.     else
  428.         (void) printf("0x%x",(unsigned long) n);
  429. }
  430.    
  431. int    findleng(tc)
  432. unsigned  tc;
  433. {
  434.     switch  ((tc >> 6) & 3)  {
  435.     case  0:
  436.         return    'b';
  437.     case  1:
  438.         return    'w';
  439.     default:
  440.         return    'l';
  441. }
  442. }
  443.  
  444. /* print @(0x4,d0.l) */
  445. void    piword(reg,disp)
  446. char * reg;
  447. unsigned  disp;
  448. {
  449. int    szc;
  450.  
  451.     (void) printf("%d(%s,", disp & 0xff, reg);
  452.     if  (disp & 0x8000) {
  453.         (void) fputs(areg[(disp >> 12) & 0x7]);
  454.         (void) putchar('.');
  455.     }
  456.     else
  457.         (void) printf("%%d%d.", (disp >> 12) & 0x7);
  458.     (void) putchar((disp & (1 << 10)) ? 'l' :'w');
  459.     (void) putchar(')');
  460. }
  461.  
  462. extern struct    commit    abstab;
  463.  
  464. void    paddr(pos)
  465. long    pos;
  466. {
  467.     t_entry    tent;
  468.     symbol    symb;
  469.  
  470.     gette(&mainfile, pos, &tent);
  471.     if  (tent.t_relsymb != NULL)  {
  472.         symb = tent.t_relsymb;
  473.         if  (symb->s_lsymb != 0)
  474.             (void) printf("L%%%u", symb->s_lsymb);
  475.         else
  476.             (void) fputs(symb->s_name, stdout);
  477.         if  (tent.t_reldisp != 0)
  478.             (void) printf("+0x%x", tent.t_reldisp);
  479.         return;
  480.     }
  481.     if ((pos = gettw(&mainfile, pos, R_LONG)) >= 0x290000)
  482.      {
  483.         register int i;
  484.         for (i=0; i < abstab.c_int; i++)
  485.             if (abstab.c_symb[i]->s_value == pos)
  486.          {         
  487.             (void) fputs(abstab.c_symb[i]->s_name, stdout);
  488.             return;
  489.          }
  490.      }
  491.     (void) printf("0x%x", pos);
  492. }
  493.  
  494. int    prea(ea, pos, sz)
  495. unsigned  ea, sz;
  496. long    pos;            /*  Address of previous word to extn  */
  497. {
  498.     unsigned  reg  =  ea & 0x7;
  499.     long    disp;
  500.     t_entry    tent;
  501.     
  502.     pos += 2;
  503.     
  504.     switch  ((ea >> 3) & 0x7)  {
  505.     case  0:
  506.         (void) printf("%%d%d", reg);
  507.         return    0;
  508.     case  1:
  509.         (void) fputs(areg[reg], stdout);
  510.         return    0;
  511.     case  2:
  512.         (void) printf("(%s)", areg[reg]);
  513.         return    0;
  514.     case  3:
  515.         (void) printf("(%s)+", areg[reg]);
  516.         return    0;
  517.     case  4:
  518.         (void) printf("-(%s)", areg[reg]);
  519.         return    0;
  520.     case  5:
  521.         disp = gettw(&mainfile, pos, R_WORD);
  522.         (void) prind(disp);
  523.         (void) printf("(%s)", areg[reg]);
  524.         return    2;
  525.     case  6:
  526.         piword(areg[reg], (unsigned) gettw(&mainfile, pos, R_WORD));
  527.         return    2;
  528.     default:
  529.         switch  (reg)  {
  530.         case  0:
  531.             disp = gettw(&mainfile, pos, R_WORD);
  532.             (void) prind(disp);
  533.             (void) putchar('.');
  534.             (void) putchar('w');
  535.             return    2;
  536.         case  1:
  537.             paddr(pos);
  538.             return    4;
  539.         case  2:{
  540.             symbol symb;
  541.             register int addr;
  542.             disp = 
  543.                 ((short) gettw(&mainfile, pos, R_WORD));
  544.               if ((addr=pos+disp) < 0  ||  
  545.                 addr-mainfile.ef_tbase > mainfile.ef_tsize ||
  546.                 (addr & 1) != 0)  
  547.                 goto skiplabs;
  548.             gette(&mainfile, addr, &tent);
  549.             if  (tent.t_relsymb != NULL)  {
  550.                 symb = tent.t_relsymb;
  551.             }
  552.             else if (tent.t_lab != NULL) {
  553.                 symb = tent.t_lab;
  554.             }
  555.             else {
  556.         skiplabs:
  557.                 (void) prind(disp);
  558.                 (void) fputs("(%pc)", stdout);
  559.                 return    2;
  560.             }
  561.             if  (symb->s_lsymb != 0)
  562.                 (void) printf("L%%%u", symb->s_lsymb);
  563.             else
  564.                 (void) fputs(symb->s_name, stdout);
  565.             if  (tent.t_reldisp != 0)
  566.                 (void) printf("+0x%x", tent.t_reldisp);
  567.             return 2;
  568.             }
  569.         case  3:
  570.             piword("%pc", (unsigned)gettw(&mainfile, pos, R_WORD));
  571.             return    2;
  572.         case  4:
  573.             (void) putchar('&');
  574.             if  (sz < 4)
  575.                 (void) prind(gettw(&mainfile, pos, R_WORD));
  576.             else
  577.                 paddr(pos);
  578.             return    sz;
  579.         default:
  580.             (void) fprintf(stderr, "Funny mode\n");
  581.             exit(220);
  582.         }
  583.     }
  584.     /*NOTREACHED*/
  585. }
  586.     
  587. int    pmove(te, pos)
  588. t_entry    *te;
  589. long    pos;
  590. {
  591.     unsigned  sz  =  2;
  592.     unsigned  tc  =  te->t_contents;
  593.     
  594.     (void) printf("mov%s\t", optab[te->t_iindex].prarg);
  595.     
  596.     if  ((tc & 0xf000) == 0x2000)
  597.         sz = 4;
  598.     
  599.     pos += prea(tc, pos, sz);
  600.     (void) putchar(',');
  601.     (void) prea(((tc >> 9) & 0x7) | ((tc >> 3) & 0x38), pos, sz);
  602. }
  603.  
  604. int    pcbch(te)
  605. t_entry    *te;
  606. {
  607.     int    cc = ((te->t_contents >> 8) & 0xf) - 2;
  608.     char    *msg;
  609.     register  symbol  ts;
  610.     
  611.     if  (cc < 0)
  612.         msg = cc < -1? "ra": "sr";
  613.     else
  614.         msg = cclist[cc];
  615.     (void) printf("b%s", msg);
  616. /* this specifically requests that 8 bit addressing be used, 
  617.         but the unixpc assembler will do this automatically.    
  618.     if  (te->t_lng < 2) {
  619.         (void) putchar('.');
  620.         (void) putchar('b');
  621.     }
  622. */
  623.     ts = te->t_relsymb;
  624.     if  (ts->s_lsymb != 0)
  625.         (void) printf("\tL%%%u", ts->s_lsymb);
  626.     else
  627.     {
  628.         (void) putchar('\t');
  629.         (void) fputs(ts->s_name, stdout);
  630.     }
  631. }
  632.  
  633. int    pdbcc(te)
  634. t_entry    *te;
  635. {
  636.     unsigned  tc  =  te->t_contents;
  637.     int    cc = ((tc >> 8) & 0xf) - 2;
  638.     char    *msg;
  639.     register  symbol  ts;
  640.     
  641.     if  (cc < 0)
  642.         msg = cc < -1? "t": "f";
  643.     else
  644.         msg = cclist[cc];
  645.     ts = te->t_relsymb;
  646.     (void) printf("db%s\t%%d%d,", msg, tc & 0x7);
  647.     if  (ts->s_lsymb)
  648.         (void) printf("L%%%u", ts->s_lsymb);
  649.     else
  650.         (void) fputs(ts->s_name, stdout);
  651. }
  652.  
  653. int    pscc(te, pos)
  654. t_entry    *te;
  655. long    pos;
  656. {
  657.     unsigned  tc  =  te->t_contents;
  658.     int    cc = ((tc >> 8) & 0xf) - 2;
  659.     char    *msg;
  660.     
  661.     if  (cc < 0)
  662.         msg = cc < -1? "t": "f";
  663.     else
  664.         msg = cclist[cc];
  665.     (void) printf("s%s\t", msg);
  666.     (void) prea(tc, pos, 1);
  667. }
  668.  
  669. int    pcs(te, pos)
  670. t_entry    *te;
  671. long    pos;
  672. {
  673.     long    disp  =  gettw(&mainfile, pos+2, R_WORD);
  674.     
  675.     (void) fputs(optab[te->t_iindex].prarg, stdout);
  676.     if  ((te->t_contents & 0xc0) == 0){
  677.          (void) fputs(".b\t&", stdout);
  678.         (void) prind(disp);
  679.         (void) fputs(",%cc", stdout);
  680.     }
  681.     else {
  682.         (void) fputs(".w\t&", stdout);
  683.         (void) prind(disp);
  684.         (void) fputs(",%sr", stdout);
  685.     }
  686. }
  687.  
  688. int    pmovc(te, pos)
  689. t_entry    *te;
  690. long    pos;
  691. {
  692.     int    disp = gettw(&mainfile, pos+2, R_WORD);
  693.     int    ctrl = ((disp >> 10) & 2) | (disp & 1);
  694.  
  695.     (void) fputs("movc\t", stdout);
  696.     if  ((te->t_contents & 1) == 0)
  697.         (void) fputs(creg[ctrl], stdout);
  698.     if  (disp & 0x8000)
  699.     {
  700.         (void) fputs(areg[(disp >> 12) & 7], stdout);
  701.         (void) putchar(',');
  702.     }
  703.     else
  704.         (void) printf("%%d%d,", disp >> 12);
  705.     if  (te->t_contents & 1)
  706.         (void) fputs(creg[ctrl], stdout);
  707. }
  708.  
  709. int    pimed(te, pos)
  710. t_entry    *te;
  711. long    pos;
  712. {
  713.     int    sz = findleng(te->t_contents);
  714.  
  715.     /* we need to swith the operands to compare instrucions. */
  716.     if (strcmp (optab[te->t_iindex].prarg, "cmp")) {
  717.         (void) printf("%s.%c\t&", optab[te->t_iindex].prarg, sz);
  718.         if  (sz == 'l')  {
  719.             paddr(pos+2);
  720.             (void) putchar(',');
  721.             (void) prea(te->t_contents, pos+4, 4);
  722.         }
  723.         else  {
  724.             (void) prind(gettw(&mainfile, pos+2, R_WORD));
  725.             (void) putchar(',');
  726.             (void) prea(te->t_contents, pos+2, 2);
  727.         }
  728.     }
  729.     else {
  730.         (void) printf("%s.%c\t", optab[te->t_iindex].prarg, sz);
  731.         if  (sz == 'l')  {
  732.             (void) prea(te->t_contents, pos+4, 4);
  733.             (void) putchar(',');
  734.             (void) putchar('&');
  735.             paddr(pos+2);
  736.         }
  737.         else  {
  738.             (void) prea(te->t_contents, pos+2, 2);
  739.             (void) putchar(',');
  740.             (void) putchar('&');
  741.             (void) prind(gettw(&mainfile, pos+2, R_WORD));
  742.         }
  743.     }
  744. }
  745.  
  746. int    pmovp(te, pos)
  747. t_entry    *te;
  748. long    pos;
  749. {
  750.     unsigned  tc  =  te->t_contents;
  751.     long    disp  =  gettw(&mainfile, pos+2, R_WORD);
  752.     int    dreg = tc >> 9;
  753.     char    *ar = areg[tc & 0x7];
  754.     
  755.     (void) fputs("movp.", stdout);
  756.     if  (tc & (1 << 6))
  757.         (void) putchar('l');
  758.     else
  759.         (void) putchar('w');
  760.  
  761.     if  (tc & (1 << 7)) {
  762.         (void) printf("\t%%d%d,", dreg);
  763.         (void) prind(disp);
  764.         (void) printf("(%s)", ar);
  765.     }
  766.     else {
  767.         (void) putchar('\t');
  768.         (void) prind(disp);
  769.         (void) printf("(%s),%%d%d", ar, dreg);
  770.     }
  771. }
  772.  
  773. int    psbit(te, pos)
  774. t_entry    *te;
  775. long    pos;
  776. {
  777.     unsigned  tc  =  te->t_contents;
  778.     
  779.     (void) printf("b%s\t&%d,", bittyp[(tc >> 6) & 0x3], gettw(&mainfile, pos+2, R_WORD));
  780.     (void) prea(tc, pos+2, 1);
  781. }
  782.  
  783. /*ARGSUSED*/
  784. int    pstop(te, pos)
  785. t_entry    *te;
  786. long    pos;
  787. {
  788.     (void) printf("stop\t&0x%x", gettw(&mainfile, pos+2, R_WORD));
  789. }
  790.  
  791. int    pdbit(te, pos)
  792. t_entry    *te;
  793. long    pos;
  794. {
  795.     unsigned  tc  =  te->t_contents;
  796.     
  797.     (void) printf("b%s\t%%d%d,", bittyp[(tc >> 6) & 0x3], (tc >> 9) & 0x7);
  798.     (void) prea(tc, pos, 1);
  799. }
  800.  
  801. int    pcs2(te, pos)
  802. t_entry    *te;
  803. long    pos;
  804. {
  805.     unsigned  tc  =  te->t_contents;
  806.     
  807.     (void) fputs("movw\t", stdout);
  808.     if  ((tc & 0xffc0) == 0x40c0)  {
  809.         (void) fputs("%sr,", stdout);
  810.         (void) prea(tc, pos, 2);
  811.     }
  812.     else  {
  813.         (void) prea(tc, pos, 2);
  814.         (void) putchar(',');
  815.         (void) fputs(optab[te->t_iindex].prarg, stdout);
  816.     }
  817. }
  818.  
  819. int    pone(te, pos)
  820. t_entry    *te;
  821. long    pos;
  822. {
  823.     unsigned  tc  =  te->t_contents;
  824.     int    sz = findleng(tc);
  825.     
  826.     (void) printf("%s.%c\t", optab[te->t_iindex].prarg, sz);
  827.     (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  828. }
  829.  
  830. int    ppea(te, pos)    /*  nbcd, pea, tas, jmp, jsr  */
  831. t_entry    *te;
  832. long    pos;
  833. {
  834.     if (! strncmp(optab[te->t_iindex].prarg, "tas") && 
  835.         (te->t_contents & 0x3f) == 0x3c) {
  836.         symbol symb;
  837.         t_entry tstr;
  838.         int counter = te->t_lng -2;
  839.         int offset = (pos += 4);
  840.         int dest;
  841.         char * sw_label;
  842.  
  843.         (void) printf("swbeg\t&%d\n", counter);
  844.  
  845.         symb = textlab(pos, pos);
  846.         printf("%s:\n", sw_label = symb->s_name);
  847.  
  848.         while (counter--) {
  849.             gette(&mainfile, pos, &tstr);
  850.             dest = tstr.t_contents + offset;
  851.              if (tstr.t_contents > 0 &&
  852.                 dest < 0x290000 && 
  853.                 ! (dest < mainfile.ef_tbase
  854.                   || dest >= mainfile.ef_tbase+mainfile.ef_tsize
  855.                   || (dest & 1) != 0 )) {
  856.                 if (symb = textlab(dest,offset))
  857.                     printf("\tshort\t%s-%s\n", 
  858.                         symb->s_name,sw_label);
  859.                 else
  860.                     printf("\tshort\t0x%x\t# Can't label destination.\n", 
  861.                             tstr.t_contents);
  862.             }
  863.             else 
  864.                 printf("\tshort\t0x%x\t# Illegal address\n", 
  865.                         tstr.t_contents);
  866.             pos += 2;
  867.         }
  868.     }
  869.     else {
  870.         (void) fputs(optab[te->t_iindex].prarg, stdout);
  871.         (void) putchar('\t');
  872.         (void) prea(te->t_contents, pos, (unsigned)(te->t_lng>2?4:2));
  873.     }
  874. }
  875.  
  876.  
  877. int    plea(te, pos)
  878. t_entry    *te;
  879. long    pos;
  880. {
  881.     (void) fputs("lea\t", stdout);
  882.     (void) prea(te->t_contents, pos, 4);
  883.     (void) putchar(',');
  884.     (void) fputs(areg[(te->t_contents >> 9) & 0x7], stdout);
  885. }
  886.  
  887. int    pdreg(te)
  888. t_entry    *te;
  889. {
  890.     (void) printf("%s\t%%d%d", optab[te->t_iindex].prarg, te->t_contents & 7);
  891. }
  892.  
  893.  
  894. int    pmvml(te, pos)
  895. t_entry    *te;
  896. long    pos;
  897. {
  898.     unsigned  tc  =  te->t_contents;
  899.     register  unsigned  dw  =  gettw(&mainfile, pos+2, R_WORD);
  900.     unsigned  sz = 4;
  901.     int    sc = 'l';
  902.     register  int    i;
  903.     register  unsigned  bit;
  904.     
  905.     (void) fputs("movm.", stdout);
  906.     if  ((tc & 0x40) == 0)  {
  907.         sc = 'w';
  908.         sz = 2;
  909.     }
  910.  
  911.     (void) putchar(sc);    
  912.     (void) putchar('\t');
  913.  
  914.     if  (tc & 0x400)  {
  915.         (void) prea(tc, pos+2, sz);
  916.         (void) printf(",&0x%x", dw);
  917.     }
  918.     else  {
  919.         (void) printf("&0x%x,", dw);
  920.         (void) prea(tc, pos+2, sz);
  921.     }
  922.     
  923.     (void) printf("\t#\t");
  924.     
  925.     if  ((tc & 0x38) == 0x20)  {
  926.         bit = 0x8000;
  927.         for  (i = 0;  i < 8;  i++)  {
  928.             if  (dw & bit)
  929.                 (void) printf(" %%d%d", i);
  930.             bit >>= 1;
  931.         }
  932.         for  (i = 0;  i < 8;  i++)  {
  933.             if  (dw & bit) {
  934.                     (void) putchar(' ');
  935.                 (void) fputs(areg[i], stdout);
  936.             }
  937.             bit >>= 1;
  938.         }
  939.     }
  940.     else  {
  941.         bit = 1;
  942.         for  (i = 0;  i < 8;  i++)  {
  943.             if  (dw & bit)
  944.                 (void) printf(" %%d%d", i);
  945.             bit <<= 1;
  946.         }
  947.         for  (i = 0;  i < 8;  i++)  {
  948.             if  (dw & bit) {
  949.                 (void) putchar(' ');
  950.                 (void) fputs(areg[i], stdout);
  951.             }
  952.             bit <<= 1;
  953.         }
  954.     }
  955. }
  956.  
  957. int    ptrap(te)
  958. t_entry    *te;
  959. {
  960.     (void) printf("trap\t&%d", te->t_contents & 0xf);
  961. }
  962.  
  963. int    plink(te, pos)
  964. t_entry    *te;
  965. long    pos;
  966. {
  967.     (void) printf("link\t%s,&%d", areg[te->t_contents & 0x7],
  968.                 gettw(&mainfile, pos+2, R_WORD));
  969. }
  970.  
  971.  
  972. int    pareg(te)
  973. t_entry    *te;
  974. {
  975.     (void) printf(optab[te->t_iindex].prarg, areg[te->t_contents & 0x7]);
  976. }
  977.  
  978. int    podreg(te, pos)
  979. t_entry    *te;
  980. long    pos;
  981. {
  982.     unsigned  tc  =  te->t_contents;
  983.     
  984.     (void) printf("%s\t", optab[te->t_iindex].prarg);
  985.     (void) prea(tc, pos, 2);
  986.     (void) printf(",%%d%d", (tc >> 9) & 0x7);
  987. }
  988.  
  989. int    pqu(te, pos)
  990. t_entry    *te;
  991. long    pos;
  992. {
  993.     unsigned  tc  =  te->t_contents;
  994.     int    sz  =  findleng(tc);
  995.     int    amt = (tc >> 9) & 0x7;
  996.     
  997.     if  (amt == 0)
  998.         amt = 8;
  999.     (void) printf("%s.%c\t&%d,", optab[te->t_iindex].prarg, sz, amt);
  1000.     (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1001. }
  1002.  
  1003. int    pmqu(te)
  1004. t_entry    *te;
  1005. {
  1006.     unsigned  tc  =  te->t_contents;
  1007.  
  1008.     (void) printf("mov.l\t&%d,%%d%d", (char)tc, (tc >> 9) & 0x7);
  1009. }
  1010.  
  1011. int    ptreg(te)
  1012. t_entry    *te;
  1013. {
  1014.     register  unsigned  tc  =  te->t_contents;
  1015.     int    rx = (tc >> 9) & 0x7;
  1016.     int    ry = tc & 0x7;
  1017.  
  1018.     (void) fputs(optab[te->t_iindex].prarg, stdout);
  1019.     (void) putchar('\t');
  1020.     if  (tc & 0x8)
  1021.         (void) printf("-(%s),-(%s)", areg[ry], areg[rx]);
  1022.     else
  1023.         (void) printf("%%d%d,%%d%d", ry, rx);
  1024. }
  1025.  
  1026. int    pcmpm(te)
  1027. t_entry    *te;
  1028. {
  1029.     register  unsigned  tc  =  te->t_contents;
  1030.  
  1031.     (void) printf("%s\t(%s)+,(%s)+", optab[te->t_iindex].prarg,
  1032.         areg[tc & 7], areg[(tc >> 9) & 7]);
  1033. }
  1034.  
  1035. int    pomode(te, pos)
  1036. t_entry    *te;
  1037. long    pos;
  1038. {
  1039.     unsigned  tc  =  te->t_contents;
  1040.     char    buf[5];
  1041.     int    sz;
  1042.     int    reg = (tc >> 9) & 7;
  1043.  
  1044.     buf[0] = '\0';
  1045.     
  1046.     switch  ((tc >> 6) & 7)  {
  1047.     case  0:
  1048.         sz = 'b';
  1049.         goto  toreg;
  1050.     case  1:
  1051.         sz = 'w';
  1052.         goto  toreg;
  1053.     case  2:
  1054.         sz = 'l';
  1055.     toreg:
  1056.          (void) sprintf(buf, "%%d%d", reg);
  1057.         goto printaft;
  1058.     case  3:
  1059.         sz = 'w';
  1060.         goto  toareg;
  1061.     case  7:
  1062.         sz = 'l';
  1063.     toareg:
  1064.         (void) sprintf(buf, "%s", areg[reg]);
  1065.     printaft:
  1066.         if (strcmp("cmp", optab[te->t_iindex].prarg)) {
  1067.             (void) printf("%s.%c\t", optab[te->t_iindex].prarg,sz);
  1068.             (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1069.             (void) putchar(',');
  1070.             (void) fputs(buf, stdout);
  1071.         }
  1072.         else {
  1073.             (void) printf("%s.%c\t%s,", optab[te->t_iindex].prarg,
  1074.                             sz, buf);
  1075.             (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1076.         }
  1077.         break;
  1078.     case  4:
  1079.         sz = 'b';
  1080.         goto  frreg;
  1081.     case  5:
  1082.         sz = 'w';
  1083.         goto  frreg;
  1084.     case  6:
  1085.         sz = 'l';
  1086.     frreg:
  1087.         (void) sprintf(buf, "%%d%d", reg);
  1088.         if (strcmp("cmp", optab[te->t_iindex].prarg)) {
  1089.             (void) printf("%s.%c\t%s,", optab[te->t_iindex].prarg, 
  1090.                     sz, buf);
  1091.             (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1092.         }
  1093.         else {
  1094.             (void) printf("%s.%c\t", optab[te->t_iindex].prarg,sz);
  1095.             (void) prea(tc, pos, (unsigned)(sz == 'l'? 4: 2));
  1096.             (void) putchar(',');
  1097.             (void) fputs(buf, stdout);
  1098.         }
  1099.     }
  1100. }
  1101.  
  1102. int    pexg(te)
  1103. t_entry    *te;
  1104. {
  1105.     unsigned  tc  =  te->t_contents;
  1106.     int    r1 = (tc >> 9) & 7, r2 = tc & 7;
  1107.  
  1108.     (void) printf("exg\t");
  1109.     
  1110.     if  ((tc & 0x00f8) == 0x0048)
  1111.     {
  1112.         (void) fputs(areg[r1], stdout);
  1113.         (void) putchar(',');
  1114.     }
  1115.     else
  1116.         (void) printf("%%d%d,", r1);
  1117.     if  (tc & 0x8)
  1118.         (void) fputs(areg[r2], stdout);
  1119.     else
  1120.         (void) printf("%%d%d", r2);
  1121. }
  1122.     
  1123. int    pmshf(te, pos)
  1124. t_entry    *te;
  1125. long    pos;
  1126. {
  1127.     unsigned  tc  =  te->t_contents;
  1128.     
  1129.     (void) printf("%s%c.w\t", shtype[(tc >> 9) & 3], tc & 0x100? 'l': 'r');
  1130.     (void) prea(tc, pos, 2);
  1131. }
  1132.  
  1133. int    pshf(te)
  1134. t_entry    *te;
  1135. {
  1136.     unsigned  tc  =  te->t_contents;
  1137.     int    sz  =  findleng(tc);
  1138.     int    disp = (tc >> 9) & 7;
  1139.  
  1140.     (void) printf("%s%c.%c\t", shtype[(tc >> 3) & 3], tc & 0x100? 'l': 'r', sz);
  1141.     if  (tc & 0x20)
  1142.         (void) printf("%%d%d", disp);
  1143.     else
  1144.         (void) printf("&%d", disp == 0? 8: disp);
  1145.     (void) printf(",%%d%d", tc & 7);
  1146. }
  1147.  
  1148. /*
  1149.  *    Find length etc of instruction.
  1150.  */
  1151.  
  1152. int    findinst(te, pos)
  1153. register  t_entry  *te;
  1154. long    pos;
  1155. {
  1156.     register  struct  opstr    *op;
  1157.     unsigned  tc  =  te->t_contents;
  1158.     int    lng = 0;
  1159.     register  int    i;
  1160.  
  1161.     te->t_type = T_BEGIN;
  1162.     te->t_bchtyp = T_NOBR;
  1163.     
  1164.     for  (op = &optab[0];  op->mask;  op++)  {
  1165.         if  ((tc & op->mask) == op->match)  {
  1166.             te->t_iindex = op - optab;
  1167.             lng = (op->opsize)(te, pos);
  1168.             break;
  1169.         }
  1170.     }
  1171.  
  1172.     for  (i = 1;  i < lng;  i++)  {
  1173.         t_entry    ctent;
  1174.         long    npos = pos+i+i;
  1175.         
  1176.         if  (npos >= endt)
  1177.             goto  clearem;
  1178.         gette(&mainfile, npos, &ctent);
  1179.         if (swbegflg) {
  1180.             ctent.t_type = T_UNKNOWN;
  1181.             putte(&mainfile, npos, &ctent);
  1182.         }
  1183.         else {
  1184.             if  (ctent.t_bdest || ctent.t_dref)  {
  1185. clearem:            for  (i--; i > 0; i--)  {
  1186.                     npos = pos + i + i;
  1187.                     gette(&mainfile, npos, &ctent);
  1188.                     ctent.t_type = T_UNKNOWN;
  1189.                     putte(&mainfile, npos, &ctent);
  1190.                 }
  1191.                 lng = 0;
  1192.                 goto  ginv;
  1193.             }
  1194.             ctent.t_type = T_CONT;
  1195.             putte(&mainfile, npos, &ctent);
  1196.         }
  1197.     }
  1198.     swbegflg = 0;
  1199.  
  1200.     if  (lng <= 0)  {
  1201. ginv:        te->t_vins = 0;
  1202.         te->t_lng = 1;
  1203.         te->t_type = T_UNKNOWN;
  1204.         te->t_bchtyp = T_NOBR;
  1205.     }
  1206.     else
  1207.         te->t_lng = lng;
  1208.     return    lng;
  1209. }
  1210.  
  1211. /*
  1212.  *    Print instruction.
  1213.  */
  1214.  
  1215. void    prinst(te, pos)
  1216. t_entry    *te;
  1217. long    pos;
  1218. {
  1219.     putchar('\t');
  1220.     (optab[te->t_iindex].opprin)(te, pos);
  1221.     putchar('\n');
  1222. }
  1223.